// 自定义Promise类
export class Promise {
    // 构造函数
    constructor(executor) {
        // 初始化状态、值、回调
        this.PromiseState = 'pending';
        this.PromiseResult = void 0;
        this.callbacks = [];
        // 记录当前Promise
        const _this = this;
        // 创建成功回调函数
        const resolve = function (value) {
            // 判断状态
            if (_this.PromiseState !== 'pending') return;
            // 改变状态和值
            _this.PromiseState = 'fulfilled';
            _this.PromiseResult = value;
            // 储存的成功异步回调被依次触发
            setTimeout(() => _this.callbacks.forEach(callback => callback.onResolved(value)));
        }
        // 创建失败回调函数
        const reject = function (reason) {
            // 判断状态
            if (_this.PromiseState !== 'pending') return;
            // 改变状态和值
            _this.PromiseState = 'rejected';
            _this.PromiseResult = reason;
            // 储存的失败异步回调被依次触发
            setTimeout(() => _this.callbacks.forEach(callback => callback.onRejected(reason)));
        }
        // 调用执行函数
        try {
            executor(resolve, reject);
        } catch (e) {
            // 一旦出现异常则执行失败回调
            reject(e);
        }
    }

    // then方法
    then(onResolved, onRejected) {
        // 设定默认成功回调方法
        if (!onResolved instanceof Function) onResolved = value => value;
        // 设定默认失败回调方法
        if (!onRejected instanceof Function) onRejected = reason => {
            throw new Error(reason);
        };
        // 记录当前Promise
        const _this = this;
        // 创建返回所需的Promise
        return new Promise((resolve, reject) => {
            // 封装执行对应回调的方法
            const callback = function (fn) {
                try {
                    // 执行本Promise的回调并获取结果
                    let result = fn(_this.PromiseResult);
                    // 判断结果类型
                    if (result instanceof Promise) {
                        // 如果是Promise类型，则将返回的Promise的回调设定为与其同步
                        setTimeout(() => result.then(value => resolve(value), reason => reject(reason)));
                    }
                    // 否则同步执行返回Promise的成功回调
                    else resolve(result);
                } catch (e) {
                    // 一旦出现异常则执行返回Promise的失败回调
                    reject(e);
                }
            }
            // 已经是成功状态：延时执行成功同步回调
            if (_this.PromiseState === 'fulfilled') setTimeout(() => callback(onResolved));
            // 已经是失败状态：延时执行失败同步回调
            if (_this.PromiseState === 'rejected') setTimeout(() => callback(onRejected));
            // 状态仍未改变：储存异步回调，等待触发
            if (_this.PromiseState === 'pending') _this.callbacks.push({
                onResolved: () => callback(onResolved),
                onRejected: () => callback(onRejected),
            });
        });
    }

    // catch方法
    catch(onRejected) {
        return this.then(void 0, onRejected);
    }

    // resolve方法
    static resolve(data) {
        // 根据参数类型调整返回Promise的状态
        return new Promise((resolve, reject) => {
            // 如果是Promise类型则设置其回调方法触发返回Promise的回调
            if (data instanceof Promise) data.then(value => resolve(value), reason => reject(reason));
            // 否则直接触发返回Promise的成功回调
            else resolve(data);
        });
    }

    // reject方法
    static reject(data) {
        // 直接触发返回Promise的失败回调
        return new Promise((resolve, reject) => reject(data));
    }

    // all方法
    static all(promises) {
        return new Promise((resolve, reject) => {
            // 记录成功Promise数量和结果
            let sum = 0;
            const results = [];
            // 循环设置Promise回调方法
            for (let i = 0; i < promises.length; i++) {
                promises[i].then(value => {
                    // 若成功，则记录结果
                    results[i] = value;
                    // 若全部成功，则触发返回Promise的成功回调
                    if (++sum === promises.length) resolve(results);
                },
                    // 若失败，则直接触发返回Promise的失败回调
                    reason => reject());
            }
        });
    }

    // race方法
    static race(promises) {
        // 第一个改变状态的Promise直接触发返回Promise的回调方法
        return new Promise((resolve, reject) => promises.forEach(promises => promises.then(value => resolve(
            value),
            reason => reject(reason))));
    }
}
